<script setup>
import { ref, onUnmounted } from 'vue'
import { ElMessage } from 'element-plus'
import mqtt from 'mqtt'

// 协议类型（mqtt/ws）
const protocol = ref('mqtt')
// 主机地址
const host = ref('124.220.40.83')
// 端口号
const port = ref('1883')
// 用户名
const username = ref('zhangsan')
// 密码
const password = ref('zhangsan')
// 客户端ID
const clientId = ref('mqtt_vue_dfc268de')

// 订阅主题相关
const subTopic = ref('') // 订阅的主题
const subQos = ref('0')  // 订阅的QoS等级

// 发布消息相关
const pubTopic = ref('')    // 发布的主题
const pubPayload = ref('')  // 发布的消息内容
const pubQos = ref('0')     // 发布的QoS等级

// 接收到的消息内容
const receivedMsg = ref('')

// MQTT客户端实例
let client = null

// 建立MQTT连接
const connectMQTT = () => {
  if (client) {
    ElMessage.warning('已连接')
    return
  }
  // 检查必要参数
  if (!host.value || !port.value || !clientId.value) {
    ElMessage.error('主机、端口、客户端ID必填')
    return
  }
  // 构建连接URL
  const url = `${protocol.value}://${host.value}:${port.value}/mqtt`
  // 创建MQTT连接
  client = mqtt.connect(url, {
    username: username.value,
    password: password.value,
    clientId: clientId.value,
    reconnectPeriod: 0 // 不自动重连
  })

  // 连接成功回调
  client.on('connect', () => {
    ElMessage.success('连接成功')
  })
  // 连接错误回调
  client.on('error', (err) => {
    ElMessage.error('连接失败: ' + err.message)
    client.end()
    client = null
  })
  // 收到消息回调
  client.on('message', (topic, message) => {
    // 累加显示所有收到的消息
    receivedMsg.value += `[${topic}] ${message.toString()}\n`
  })
  // 连接关闭回调
  client.on('close', () => {
    ElMessage.info('连接已断开')
    client = null
  })
}

// 断开MQTT连接
const disconnectMQTT = () => {
  if (client) {
    client.end()
    client = null
    ElMessage.success('已断开连接')
  } else {
    ElMessage.warning('未连接')
  }
}

// 订阅主题
const subscribeTopic = () => {
  if (!client) {
    ElMessage.error('请先建立连接')
    return
  }
  if (!subTopic.value) {
    ElMessage.error('请输入订阅主题')
    return
  }
  // 订阅指定主题和QoS
  client.subscribe(subTopic.value, { qos: Number(subQos.value) }, (err) => {
    if (err) {
      ElMessage.error('订阅失败')
    } else {
      ElMessage.success('订阅成功')
    }
  })
}

// 取消订阅主题
const unsubscribeTopic = () => {
  if (!client) {
    ElMessage.error('请先建立连接')
    return
  }
  if (!subTopic.value) {
    ElMessage.error('请输入订阅主题')
    return
  }
  // 取消订阅指定主题
  client.unsubscribe(subTopic.value, (err) => {
    if (err) {
      ElMessage.error('取消订阅失败')
    } else {
      ElMessage.success('取消订阅成功')
    }
  })
}

// 发布消息到指定主题
const publishMsg = () => {
  if (!client) {
    ElMessage.error('请先建立连接')
    return
  }
  if (!pubTopic.value) {
    ElMessage.error('请输入发布主题')
    return
  }
  // 发布消息，带QoS
  client.publish(pubTopic.value, pubPayload.value, { qos: Number(pubQos.value) }, (err) => {
    if (err) {
      ElMessage.error('发布失败')
    } else {
      ElMessage.success('发布成功')
    }
  })
}

// 页面卸载时自动断开MQTT连接，防止资源泄漏
onUnmounted(() => {
  if (client) {
    client.end()
    client = null
  }
})
</script>

<template>
  <!-- 配置信息区域 -->
  <el-card class="box-card" style="margin-bottom: 20px;">
    <div style="text-align: center; font-weight: bold; font-size: 18px; margin-bottom: 10px;">配置信息</div>
    <el-form :inline="true" label-width="80px">
      <el-row :gutter="20">
        <el-col :span="6">
          <el-form-item label="选择协议">
            <!-- 协议选择下拉框 -->
            <el-select v-model="protocol" placeholder="Select" style="width: 100%">
              <el-option label="MQTT" value="mqtt" />
              <el-option label="WS" value="ws" />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item label="主机地址">
            <!-- 主机地址输入框 -->
            <el-input v-model="host" placeholder="" />
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item label="端口号">
            <!-- 端口号输入框 -->
            <el-input v-model="port" placeholder="8083/8084" />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="20">
        <el-col :span="6">
          <el-form-item label="用户名">
            <!-- 用户名输入框 -->
            <el-input v-model="username" placeholder="" />
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item label="密码">
            <!-- 密码输入框 -->
            <el-input v-model="password" type="password" placeholder="" />
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item label="客户端ID">
            <!-- 客户端ID输入框 -->
            <el-input v-model="clientId" placeholder="" />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row style="margin-top: 10px;">
        <el-col :span="24" style="text-align: center;">
          <!-- 建立连接、断开连接按钮 -->
          <el-button type="primary" @click="connectMQTT">建立连接</el-button>
          <el-button type="danger" @click="disconnectMQTT">断开连接</el-button>
        </el-col>
      </el-row>
    </el-form>
  </el-card>

  <!-- 订阅主题区域 -->
  <el-card class="box-card" style="margin-bottom: 20px;">
    <div style="text-align: center; font-weight: bold; font-size: 18px; margin-bottom: 10px;">订阅主题</div>
    <el-form :inline="true">
      <el-row :gutter="20">
        <el-col :span="8">
          <el-form-item label="Topic">
            <!-- 订阅主题输入框 -->
            <el-input v-model="subTopic" placeholder="" />
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="QoS">
            <!-- QoS选择下拉框 -->
            <el-select v-model="subQos" placeholder="Select" style="width: 100%">
              <el-option label="0" value="0" />
              <el-option label="1" value="1" />
              <el-option label="2" value="2" />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="8" style="display: flex; align-items: center;">
          <!-- 订阅、取消订阅按钮 -->
          <el-button type="primary" style="margin-right: 10px;" @click="subscribeTopic">订阅主题</el-button>
          <el-button @click="unsubscribeTopic">取消订阅</el-button>
        </el-col>
      </el-row>
    </el-form>
  </el-card>

  <!-- 发布消息区域 -->
  <el-card class="box-card" style="margin-bottom: 20px;">
    <div style="text-align: center; font-weight: bold; font-size: 18px; margin-bottom: 10px;">发布消息</div>
    <el-form :inline="true">
      <el-row :gutter="20">
        <el-col :span="6">
          <el-form-item label="Topic">
            <!-- 发布主题输入框 -->
            <el-input v-model="pubTopic" placeholder="" />
          </el-form-item>
        </el-col>
        <el-col :span="10">
          <el-form-item label="Payload">
            <!-- 发布内容输入框 -->
            <el-input v-model="pubPayload" placeholder="" />
          </el-form-item>
        </el-col>
        <el-col :span="4">
          <el-form-item label="QoS">
            <!-- 发布QoS选择下拉框 -->
            <el-select v-model="pubQos" placeholder="Select" style="width: 100%">
              <el-option label="0" value="0" />
              <el-option label="1" value="1" />
              <el-option label="2" value="2" />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="4" style="display: flex; align-items: center;">
          <!-- 发布消息按钮 -->
          <el-button type="primary" @click="publishMsg">发布消息</el-button>
        </el-col>
      </el-row>
    </el-form>
  </el-card>

  <!-- 接收消息区域 -->
  <el-card class="box-card">
    <div style="text-align: center; font-weight: bold; font-size: 18px; margin-bottom: 10px;">接收到的消息</div>
    <!-- 只读多行文本框，显示所有接收到的消息 -->
    <el-input type="textarea" :rows="8" v-model="receivedMsg" readonly />
  </el-card>
</template>

<style scoped>
/* 卡片样式居中和宽度限制 */
.box-card {
  max-width: 1000px;
  margin: 0 auto 20px auto;
}
</style>